package com.tyros.web.support.i18n;

import lombok.AllArgsConstructor;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;

/**
 * 国际化工具类
 *
 * @author zhangshuaiyin
 * @date 2022/7/14 9:44
 */
public class I18nUtils {
    private static final MessageSource MESSAGE_SOURCE;

    static {
        ResourceBundleMessageSource bundleMessageSource = new ResourceBundleMessageSource();
        bundleMessageSource.setDefaultEncoding("UTF-8");
        bundleMessageSource.setUseCodeAsDefaultMessage(true);
        bundleMessageSource.setDefaultLocale(Locale.US);
        bundleMessageSource.setCacheSeconds(5);
        bundleMessageSource.setBasenames("i18n/messages");
        Locale.setDefault(Locale.US);
        MESSAGE_SOURCE = bundleMessageSource;
    }

    public static String getMessage(String code) {
        return getMessage(code, new Object[]{});
    }

    public static String getMessage(String code, Object... params) {
        return getMessage(code, locale(), params);
    }

    public static String getMessage(String code, Locale locale, Object... params) {
        return getMessage(code, code + ": no such message code.", locale, params);
    }

    public static String getMessage(String code, String defaultValue, Locale locale, Object... params) {
        try {
            return MESSAGE_SOURCE == null ? code : MESSAGE_SOURCE.getMessage(code, params, defaultValue, locale);
        } catch (NoSuchMessageException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Locale locale() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (Objects.isNull(requestAttributes)) {
            return Locale.getDefault();
        }
        String lang = Optional.ofNullable(((ServletRequestAttributes) requestAttributes).getRequest().getHeader("lang")).orElse("zh");

        return Optional.ofNullable(LocaleEnum.localeOf(lang)).orElse(Locale.getDefault());
    }

    @AllArgsConstructor
    enum LocaleEnum {
        /**
         * 国际化请求头
         */
        EN_US(Arrays.asList("en_us", "en"), Locale.US),
        ZH_CN(Arrays.asList("zh_cn", "zh"), Locale.SIMPLIFIED_CHINESE),
        ;
        private final List<String> lang;
        private final Locale locale;

        public static Locale localeOf(String lang) {
            return Arrays.stream(values()).filter(localeEnum -> localeEnum.lang.contains(lang.toLowerCase())).findAny().orElse(LocaleEnum.EN_US).locale;
        }
    }
}
